package com.mushuilingfeng.ddd.user.base;

import com.mushuilingfeng.ddd.user.domain.base.BusinessException;
import com.mushuilingfeng.ddd.user.domain.base.DomainArgumentException;
import com.mushuilingfeng.ddd.user.domain.base.Ii8nCode;
import com.mushuilingfeng.ddd.user.domain.base.service.Ii8nService;
import com.mushuilingfeng.spring.common.BaseResult;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author
 * @date 2024/9/19
 */
@ControllerAdvice
@Slf4j
@AllArgsConstructor
public class GlobalExceptionHandler {
    private final Ii8nService ii8nService;

    private String getIi8nMessage(Ii8nCode ii8nCode) {
        return ii8nService.getMessage(ii8nCode.getCode(), ii8nCode.getDefaultValue());
    }

    private String getIi8nMessage(String code) {
        return ii8nService.getMessage(code, "");
    }

    @ExceptionHandler(BusinessException.class)
    public ResponseEntity<BaseResult<Void>> businessException(BusinessException e) {
        return new ResponseEntity<>(BaseResult.fail(e.getErrorCode(), e.getErrorMsg()), HttpStatus.BAD_REQUEST);
    }

    @ExceptionHandler(DomainArgumentException.class)
    public ResponseEntity<BaseResult<Void>> domainArgumentException(DomainArgumentException e) {
        return new ResponseEntity<>(BaseResult.fail(e.getErrorCode(), e.getErrorMsg()), HttpStatus.BAD_REQUEST);
    }


    @ExceptionHandler(Exception.class)
    public ResponseEntity<BaseResult<Void>> defaultException(Exception e) {
        log.error("系统错误", e);
        return new ResponseEntity<>(BaseResult.fail(getIi8nMessage(Ii8nCode.SYSTEM_ERROR)), HttpStatus.INTERNAL_SERVER_ERROR);
    }

    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseEntity<BaseResult<Map<String, String>>> handleValidationExceptions(MethodArgumentNotValidException ex) {
        BindingResult result = ex.getBindingResult();
        List<FieldError> fieldErrors = result.getFieldErrors();
        Map<String, String> map = new HashMap<>();
        fieldErrors.forEach(fieldError -> {
            if (fieldError.getDefaultMessage() == null) {
                map.put(fieldError.getField(), "");
                return;
            }
            if (fieldError.getDefaultMessage().startsWith("{") && fieldError.getDefaultMessage().endsWith("}")) {
                String code = fieldError.getDefaultMessage().substring(1, fieldError.getDefaultMessage().length() - 1);
                map.put(fieldError.getField(), getIi8nMessage(code));
            } else {
                map.put(fieldError.getField(), fieldError.getDefaultMessage());
            }
        });
        // 处理错误信息
        return ResponseEntity.badRequest().body(BaseResult.fail(getIi8nMessage(Ii8nCode.PARAM_INVALID), map));
    }

}
